package city.spring.service.mealService.impl;

import city.spring.domain.entity.mealService.FoodInfoEntity;
import city.spring.domain.entity.mealService.MealTimeEntity;
import city.spring.domain.entity.mealService.RecipesWeekEntity;
import city.spring.domain.entity.mealService.WeekMealEntity;
import city.spring.modules.ext.EntityExtUtils;
import city.spring.modules.ext.entity.RecipesMealTimeExt;
import city.spring.modules.ext.service.MealFoodExtService;
import city.spring.modules.ext.service.RecipesMealTimeExtService;
import city.spring.repository.mealService.RecipesWeekRepository;
import city.spring.service.mealService.FoodInfoService;
import city.spring.service.mealService.MealTimeService;
import city.spring.service.mealService.RecipesWeekService;
import city.spring.service.mealService.WeekMealService;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.text.SimpleDateFormat;
import java.time.DayOfWeek;
import java.time.ZoneId;
import java.util.*;
import java.util.stream.Collectors;

@Service
@Transactional(rollbackFor = Throwable.class)
public class RecipesWeekServiceImpl extends ServiceImpl<RecipesWeekRepository, RecipesWeekEntity> implements RecipesWeekService {

    private WeekMealService weekMealService;
    private MealFoodExtService mealFoodExtService;
    private MealTimeService mealTimeService;
    private FoodInfoService foodInfoService;
    private RecipesMealTimeExtService recipesMealTimeExtService;

    public RecipesWeekServiceImpl(WeekMealService weekMealService, MealFoodExtService mealFoodExtService, MealTimeService mealTimeService, FoodInfoService foodInfoService, RecipesMealTimeExtService recipesMealTimeExtService) {
        this.weekMealService = weekMealService;
        this.mealFoodExtService = mealFoodExtService;
        this.mealTimeService = mealTimeService;
        this.foodInfoService = foodInfoService;
        this.recipesMealTimeExtService = recipesMealTimeExtService;
    }

    @Override
    public void saveRecipesWeek(RecipesWeekEntity entity) {
//        RecipesWeekEntity findEntity = lambdaQuery().eq(RecipesWeekEntity::getStartTime,entity.getStartTime()).one();
//        if(findEntity!=null){
//            throw new RuntimeException("该时间段的周期已存在，请勿再次添加！");
//        }
        SimpleDateFormat format = new SimpleDateFormat("E");
        String str = format.format(Date.from(entity.getStartTime().atStartOfDay(ZoneId.systemDefault()).toInstant()));
        if (!str.equals("星期一")) {
            throw new RuntimeException("请选择星期一作为一个周期的开始");
        }
        entity.setWeek(entity.getStartTime());
        entity.setEndTime(entity.getStartTime().plusDays(6));
        save(entity);
        for (int i = 1; i <= 7; i++) {
            for (int j = 1; j <= entity.getMealTime().size(); j++) {
                WeekMealEntity weekMealEntity = new WeekMealEntity();
                weekMealEntity.setMealTime(j);
                weekMealEntity.setMealDay(i);
                weekMealEntity.setWeekId(entity.getId());
                boolean saveWeekMeal = weekMealService.save(weekMealEntity);
                if (!saveWeekMeal) {
                    throw new RuntimeException("生成餐次安排表失败");
                }
            }
        }
        setRecipesMealTime(entity);
    }

    @Override
    public void updateRecipesWeek(RecipesWeekEntity entity) {
        lambdaUpdate()
                .set(RecipesWeekEntity::getWeek, entity.getWeek())
                .set(RecipesWeekEntity::getStartTime, entity.getStartTime())
                .set(RecipesWeekEntity::getEndTime, entity.getEndTime())
                .set(RecipesWeekEntity::getPrize, entity.getPrize())
                .set(RecipesWeekEntity::getRegistrant, entity.getRegistrant())
                .set(RecipesWeekEntity::isStatue, entity.isStatue())
                .eq(RecipesWeekEntity::getId, entity.getId())
                .update();
        setRecipesMealTime(entity);
    }

    @Override
    public void deleteRecipesWeek(String primaryKey) {
        removeById(primaryKey);
        List<WeekMealEntity> weekMealEntities = weekMealService.getWeekMeal(primaryKey);
        for (int i = 0; i < weekMealEntities.size(); i++) {
            weekMealService.deleteWeekMeal(weekMealEntities.get(i).getId());
        }
        recipesMealTimeExtService.lambdaUpdate().eq(RecipesMealTimeExt::getRecipesId, primaryKey).remove();
    }

    @Override
    public void deleteRecipesWeek(List<String> primaryKeys) {
        removeByIds(primaryKeys);
        for (int i = 0; i < primaryKeys.size(); i++) {
            List<WeekMealEntity> weekMealEntities = weekMealService.getWeekMeal(primaryKeys.get(i));
            for (int j = 0; j < weekMealEntities.size(); i++) {
                weekMealService.deleteWeekMeal(weekMealEntities.get(j).getId());
            }
            recipesMealTimeExtService.lambdaUpdate().in(RecipesMealTimeExt::getRecipesId, primaryKeys).remove();
        }
    }

    @Override
    public void loadWeekMeal(RecipesWeekEntity entity) {
        String weekId = entity.getId();
        List<WeekMealEntity> entities = weekMealService.getWeekMeal(weekId);
        entity.setChildren(entities);
    }

    @Override
    public void loadWeekMeal(List<RecipesWeekEntity> entities) {
        entities.forEach(this::loadWeekMeal);
    }

    @Override
    public List<RecipesWeekEntity> getRecipesWeek(String recipesId) {
        return baseMapper.getRecipesWeek(recipesId);
    }

    @Override
    public void loadMealTime(RecipesWeekEntity entity) {
        List<MealTimeEntity> entities = mealTimeService.getRecipesMealTime(entity.getId());
        entity.setMealTime(entities);
    }

    @Override
    public void loadMealTime(List<RecipesWeekEntity> entities) {
        entities.forEach(this::loadMealTime);
    }

    @Override
    public Map<DayOfWeek, List<FoodInfoEntity>> getWeekFoodAll(RecipesWeekEntity entity) {
        List<FoodInfoEntity> foodInfoEntities = new LinkedList<>();
        for (int i = 0; i < 7; i++) {
            List<FoodInfoEntity> dailyFoods = foodInfoService.getWeekFoodAll(entity.getStartTime().plusDays(i));
            for (int j = 0; j < dailyFoods.size(); j++) {
                dailyFoods.get(j).setDateTag(entity.getStartTime().plusDays(i).getDayOfWeek());
            }
            foodInfoEntities.addAll(dailyFoods);
        }
        List<List<FoodInfoEntity>> currentFood = new LinkedList<>();
        foodInfoEntities.stream().collect(Collectors.groupingBy(FoodInfoEntity::getDateTag, Collectors.toList()))
                .forEach((dateTag, foodListByDateTag) -> {
                    currentFood.add(foodListByDateTag);
                });
        Map<DayOfWeek, List<FoodInfoEntity>> newMap = new HashMap<>();
        for (int i = 0; i < currentFood.size(); i++) {
            newMap.put(currentFood.get(i).get(0).getDateTag(), currentFood.get(i));
        }
        return newMap;
    }

    @Override
    public void setRecipesMealTime(RecipesWeekEntity entity) {
        EntityExtUtils.repairRelation(recipesMealTimeExtService, entity,
                RecipesWeekEntity::getId, RecipesWeekEntity::getMealTime, MealTimeEntity::getId,
                RecipesMealTimeExt::new, RecipesMealTimeExt::getRecipesId);
    }

}
